home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 7684 / 7684.xpi / chrome / firefm.jar / content / fmFeeds.js < prev    next >
Text File  |  2009-06-02  |  11KB  |  299 lines

  1. /**
  2.  * Copyright (c) 2008, Jose Enrique Bolanos, Jorge Villalobos
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions are met:
  7.  *
  8.  *  * Redistributions of source code must retain the above copyright notice,
  9.  *    this list of conditions and the following disclaimer.
  10.  *  * Redistributions in binary form must reproduce the above copyright notice,
  11.  *    this list of conditions and the following disclaimer in the documentation
  12.  *    and/or other materials provided with the distribution.
  13.  *  * Neither the name of Jose Enrique Bolanos, Jorge Villalobos nor the names
  14.  *    of its contributors may be used to endorse or promote products derived
  15.  *    from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  20.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  21.  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  22.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  23.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  24.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  25.  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  26.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28.  **/
  29.  
  30. /**
  31.  * This object manages the lists of feeds on the toolbar and menu.
  32.  */
  33. FireFMChrome.Feeds = {
  34.   /* The maximum amount of items to be shown on a popup. */
  35.   _MAX_ITEM_COUNT : 15,
  36.   /* Ids for elements where the feed items will be added. */
  37.   _FEEDS :
  38.     [ [ "firefm-mm-station-friends", "firefm-tb-station-friends",
  39.         "firefm-status-tb-station-friends" ],
  40.       [ "firefm-mm-station-neighbors", "firefm-tb-station-neighbors",
  41.         "firefm-status-tb-station-neighbors" ],
  42.       [ "firefm-mm-station-top-artists", "firefm-tb-station-top-artists",
  43.         "firefm-status-tb-station-top-artists" ],
  44.       [ "firefm-mm-station-similar-artists",
  45.         "firefm-tb-station-similar-artists",
  46.         "firefm-status-tb-station-similar-artists" ] ],
  47.  
  48.   /* Logger for this object. */
  49.   _logger : null,
  50.   /* menuitem element used to show the full list for a cut feed. */
  51.   _fullListItem : null,
  52.   /* String bundle in the overlay. */
  53.   _bundle : null,
  54.  
  55.   /**
  56.    * Initializes the object.
  57.    */
  58.   init : function() {
  59.     this._logger = FireFM.getLogger("FireFMChrome.Feeds");
  60.     this._logger.debug("init");
  61.  
  62.     // get the string bundle.
  63.     this._bundle = document.getElementById("firefm-string-bundle");
  64.  
  65.     // generate the 'full list' menu item.
  66.     this._fullListItem = document.createElement("menuitem");
  67.     this._fullListItem.setAttribute("observes", "firefm-full-list-broadcaster");
  68.  
  69.     // set all feeds to empty.
  70.     this._clearAllFeeds();
  71.     // try to load all feeds in case this is not the first window being opened.
  72.     this._loadFeed(FireFM.Feeds.FEED_SIMILAR_ARTISTS);
  73.  
  74.     if (null != FireFM.Login.userName) {
  75.       this._loadFeed(FireFM.Feeds.FEED_TOP_ARTISTS);
  76.       this._loadFeed(FireFM.Feeds.FEED_FRIENDS);
  77.       this._loadFeed(FireFM.Feeds.FEED_NEIGHBORS);
  78.     }
  79.  
  80.     // add observers.
  81.     FireFM.obsService.addObserver(this, FireFM.Feeds.TOPIC_FEED_LOADED, false);
  82.     FireFM.obsService.addObserver(this, FireFM.Feeds.TOPIC_FEED_CLEARED, false);
  83.   },
  84.  
  85.   /**
  86.    * Unloads the object.
  87.    */
  88.   uninit : function() {
  89.     this._logger.debug("uninit");
  90.     // remove observers.
  91.     FireFM.obsService.removeObserver(this, FireFM.Feeds.TOPIC_FEED_LOADED);
  92.     FireFM.obsService.removeObserver(this, FireFM.Feeds.TOPIC_FEED_CLEARED);
  93.   },
  94.  
  95.   /**
  96.    * Loads the feed of the specified type into the corresponding elements.
  97.    * @param aFeedType the type of feed that will be loaded.
  98.    */
  99.   _loadFeed : function(aFeedType) {
  100.     this._logger.debug("_loadFeed. Type: " + aFeedType);
  101.  
  102.     let elementIds = this._FEEDS[aFeedType];
  103.     let idCount = elementIds.length;
  104.  
  105.     if (0 < idCount) {
  106.       let isMac = (FireFM.OS_MAC == FireFM.getOperatingSystem());
  107.       let elements = new Array();
  108.       let elementCount;
  109.       let element;
  110.  
  111.       for (let i = 0; i < idCount; i++) {
  112.         element = document.getElementById(elementIds[i]);
  113.  
  114.         if (null != element) {
  115.           elements.push(element);
  116.         }
  117.       }
  118.  
  119.       elementCount = elements.length;
  120.  
  121.       if (0 < elementCount) {
  122.         let feed = FireFM.Feeds.getFeed(aFeedType, this._MAX_ITEM_COUNT);
  123.         let feedItemCount = feed.length; // limited.
  124.  
  125.         if (0 < feedItemCount) {
  126.           let popup = document.createElement("menupopup");
  127.           let feedSize = FireFM.Feeds.getFeedSize(aFeedType); // total.
  128.           let feedItem;
  129.           let menuItem;
  130.  
  131.           // build the menupopup with all the corresponding feed items.
  132.           for (let i = 0; i < feedItemCount; i++) {
  133.             feedItem = feed[i];
  134.             menuItem = document.createElement("menuitem");
  135.  
  136.             menuItem.setAttribute("label", feedItem.name);
  137.             menuItem.setAttribute("fmurl", feedItem.url);
  138.  
  139.             // XXX: don't use icon images on Mac because they're buggy and
  140.             // causing crashes.
  141.             if (!isMac) {
  142.               menuItem.setAttribute(
  143.                 "class", "menuitem-iconic firefm-menuitem-iconic");
  144.               menuItem.setAttribute("image", feedItem.imagePath);
  145.             }
  146.  
  147.             popup.appendChild(menuItem);
  148.           }
  149.  
  150.           // if the feed items were cut, add an item to show the full list.
  151.           if (feedSize > feedItemCount) {
  152.             menuItem = document.createElement("menuseparator");
  153.             popup.appendChild(menuItem);
  154.             popup.appendChild(this._fullListItem.cloneNode(true));
  155.           }
  156.  
  157.           // add the menu popup to all associated elements.
  158.           for (let i = 0; i < elementCount; i++) {
  159.             element = elements[i];
  160.  
  161.             if (null != element.firstChild) {
  162.               // remove the menupopup to clear all existing elements.
  163.               element.removeChild(element.firstChild);
  164.             }
  165.  
  166.             element.appendChild((0 == i) ? popup : popup.cloneNode(true));
  167.           }
  168.         }
  169.       }
  170.     }
  171.   },
  172.  
  173.   /**
  174.    * Clears all feeds.
  175.    */
  176.   _clearAllFeeds : function() {
  177.     this._logger.trace("_clearAllFields");
  178.  
  179.     for (let i = 0; i < this._FEEDS.length; i++) {
  180.       this._clearFeed(i);
  181.     }
  182.   },
  183.  
  184.   /**
  185.    * Clears the feed of the given type.
  186.    * @param aFeedType The type of the feed to clear.
  187.    */
  188.   _clearFeed : function(aFeedType) {
  189.     this._logger.trace("_clearFeed");
  190.  
  191.     let feed = this._FEEDS[aFeedType];
  192.     let menu;
  193.     let menuItem;
  194.     let popup;
  195.  
  196.     for (let i = 0; i < feed.length; i++) {
  197.       menu = document.getElementById(feed[i]);
  198.  
  199.       if (null != menu.firstChild) {
  200.         // remove the menupopup to clear all elements.
  201.         menu.removeChild(menu.firstChild);
  202.       }
  203.  
  204.       // add a popup with an Empty menu item.
  205.       popup = document.createElement("menupopup");
  206.       menuItem = document.createElement("menuitem");
  207.       menuItem.setAttribute(
  208.         "label",  this._bundle.getString("firefm.emptyMenu.label"));
  209.       menuItem.setAttribute("disabled", true);
  210.       popup.appendChild(menuItem);
  211.       menu.appendChild(popup);
  212.     }
  213.   },
  214.  
  215.   /**
  216.    * Opens a dialog with the full list from the feed, allowing the user to
  217.    * choose one item from it. When the user chooses an item, the corresponding
  218.    * action (such as opening a station) is run.
  219.    * @param aEvent the event that triggered this.
  220.    */
  221.   showFullList : function(aEvent) {
  222.     this._logger.debug("showFullList");
  223.  
  224.     let listResult = { selected : null };
  225.     let elementId = aEvent.target.parentNode.parentNode.id;
  226.     let feedType;
  227.     let title;
  228.     let message;
  229.  
  230.     switch (elementId) {
  231.       case "firefm-mm-station-similar-artists":
  232.       case "firefm-tb-station-similar-artists":
  233.       case "firefm-status-tb-station-similar-artists":
  234.         title = this._bundle.getString("firefm.fullList.artistTitle.label");
  235.         message = this._bundle.getString("firefm.fullList.artist.label");
  236.         feedType = FireFM.Feeds.FEED_SIMILAR_ARTISTS;
  237.         break;
  238.       case "firefm-mm-station-top-artists":
  239.       case "firefm-tb-station-top-artists":
  240.       case "firefm-status-tb-station-top-artists":
  241.         title = this._bundle.getString("firefm.fullList.artistTitle.label");
  242.         message = this._bundle.getString("firefm.fullList.artist.label");
  243.         feedType = FireFM.Feeds.FEED_TOP_ARTISTS;
  244.         break;
  245.       case "firefm-mm-station-friends":
  246.       case "firefm-tb-station-friends":
  247.       case "firefm-status-tb-station-friends":
  248.         title = this._bundle.getString("firefm.fullList.friendTitle.label");
  249.         message = this._bundle.getString("firefm.fullList.friend.label");
  250.         feedType = FireFM.Feeds.FEED_FRIENDS;
  251.         break;
  252.       case "firefm-mm-station-neighbors":
  253.       case "firefm-tb-station-neighbors":
  254.       case "firefm-status-tb-station-neighbors":
  255.         title = this._bundle.getString("firefm.fullList.neighborTitle.label");
  256.         message = this._bundle.getString("firefm.fullList.neighbor.label");
  257.         feedType = FireFM.Feeds.FEED_NEIGHBORS;
  258.         break;
  259.     }
  260.  
  261.     window.openDialog(
  262.       "chrome://firefm/content/fmFeedListDialog.xul", "firefm-feed-list-dialog",
  263.       "chrome,modal,centerscreen,titlebar,toolbar,resizable=no", feedType,
  264.       title, message, listResult);
  265.  
  266.     if (null != listResult.selected) {
  267.       switch (feedType) {
  268.         case FireFM.Feeds.FEED_SIMILAR_ARTISTS:
  269.         case FireFM.Feeds.FEED_TOP_ARTISTS:
  270.           FireFMChrome.BrowserOverlay.verifyStation(
  271.             listResult.selected.name, FireFM.Station.TYPE_ARTIST);
  272.           break;
  273.         case FireFM.Feeds.FEED_FRIENDS:
  274.         case FireFM.Feeds.FEED_NEIGHBORS:
  275.           FireFM.Station.setStation(
  276.             listResult.selected.name, FireFM.Station.TYPE_USER);
  277.           FireFM.Station.play();
  278.           break;
  279.       }
  280.     }
  281.   },
  282.  
  283.   /**
  284.    * Observes topic notifications.
  285.    * @param aSubject The object that experienced the change.
  286.    * @param aTopic The topic being observed.
  287.    * @param aData The data relating to the change.
  288.    */
  289.   observe : function(aSubject, aTopic, aData) {
  290.     this._logger.debug("observe");
  291.  
  292.     if (FireFM.Feeds.TOPIC_FEED_LOADED == aTopic) {
  293.       this._loadFeed(parseInt(aData));
  294.     } else if (FireFM.Feeds.TOPIC_FEED_CLEARED == aTopic) {
  295.       this._clearFeed(parseInt(aData));
  296.     }
  297.   }
  298. };
  299.